/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: rtos gic enhance feature functions
 * Author: huyizhou
 * Create: 2023-09-14
 */

#ifdef CONFIG_RTOS_HAL_GIC_INIT_IRQS_ACTIVE_CLEAR
void gic_eois(u32 active, int irq_off, void __iomem *cpu_base)
{
	int bit = -1;

	for_each_set_bit(bit, (unsigned long *)&active, 32)
		writel_relaxed(bit + irq_off, cpu_base + GIC_CPU_EOI);
}
void gic_dist_clear_active(void __iomem *dist_base,
		void __iomem *cpu_base, int gic_irqs)
{
	int irq, offset;
	u32 active;

	for (irq = 0; irq < gic_irqs; irq += 32) {
		offset = GIC_DIST_ACTIVE_SET + irq * 4 / 32;
		active = readl_relaxed(dist_base + offset);

		if (!active)
			continue;

		gic_eois(active, irq, cpu_base);
	}
}
#endif

#ifdef CONFIG_RTOS_HAL_SET_IRQPRIORITY
static int gic_set_pri(struct irq_data *d, u8 prio)
{
	void __iomem *reg = NULL;

	if (!d) {
		pr_err("[%s]%d get irq data err!\n", __func__, __LINE__);
		return -EINVAL;
	}

	if (prio < MIN_IRQ_PRI_NUM || prio >= MAX_IRQ_PRI_NUM) {
		pr_err("[%s]%d prio %u out of restriction\n",
					__func__, __LINE__, prio);
		return -EINVAL;
	}

	if (d->irq < MIN_IRQ_NUM) {
		pr_err("[%s]%d irq num %d out of restriction\n",
					__func__, __LINE__, d->irq);
		return -EINVAL;
	}

	reg = gic_data_dist_base(gic_data) + GIC_DIST_PRI + gic_irq(d);
	writeb_relaxed(prio, reg);

	return 0;
}

static int gic_get_pri(struct irq_data *d, u8 *prio)
{
	void __iomem *reg = NULL;

	if (!prio)
		return -EINVAL;

	if (!d) {
		pr_err("[%s]%d irq get virq err!\n", __func__, __LINE__);
		return -EINVAL;
	}

	if (d->irq < MIN_IRQ_NUM) {
		pr_err("[%s]%d irq nr out of restriction\n", __func__, __LINE__);
		return -EINVAL;
	}

	reg = gic_data_dist_base(gic_data) + GIC_DIST_PRI + gic_irq(d);
	*prio = readb_relaxed(reg);

	return 0;
}
#endif
